package com.evolved.automata.android.bots.speechbot;
import android.content.*;
import android.speech.tts.*;
import java.util.concurrent.*;


public class SpeechController implements TextToSpeech.OnInitListener
{
	TextToSpeech speechEngine;
	private final int PLAY_CURRENT_MESSAGE=0;
	private final int STOP_CURRENT_MESSAGE=1;
	private final int MOVE_TO_NEXT_MESSAGE=2;
	private final int MOVE_TO_PREV_MESSAGE=4;
	private final int RESTART_CURRENT_MESSAGE=5;
	private final int GET_POSITION=7;
	private final int GET_TOTAL_MESSAGES=8;
	private final int QUIT=6;
	
	String[] messages=null;
	int currentPosition=0;
	int totalMessages=0;
	boolean speechReadyP=false;
	Thread controlThread;
	LinkedBlockingQueue<Integer> messageQueue;
	LinkedBlockingQueue<Integer> positionQueue;
	
	
	public SpeechController(Context context)
	{
		
		speechEngine = new TextToSpeech(context, this);
		messageQueue = new LinkedBlockingQueue<Integer>();
		positionQueue = new LinkedBlockingQueue<Integer>();
		Runnable messageInterpreter = new Runnable(){
			public void run()
			{
				int messageId=0;
				
				try
				{
					messageId = messageQueue.take();
					while (messageId!=QUIT)
					{
						switch (messageId)
						{
							case PLAY_CURRENT_MESSAGE:
								if ((currentPosition<totalMessages)&&(speechReadyP))
								{
									if (speechEngine.isSpeaking())
										speechEngine.stop();
									speechEngine.speak(messages[currentPosition],TextToSpeech.QUEUE_FLUSH, null);
								}
								break;
							case STOP_CURRENT_MESSAGE:
								speechEngine.stop();
								break;
							case MOVE_TO_NEXT_MESSAGE:
								if (currentPosition<totalMessages-1)
								{
									currentPosition=Math.min(totalMessages-1, currentPosition+1);
									
									messageQueue.put(PLAY_CURRENT_MESSAGE);
								}
								break;
							case MOVE_TO_PREV_MESSAGE:
								if (currentPosition>0)
								{
									currentPosition=Math.max(0, currentPosition-1);
									
									messageQueue.put(PLAY_CURRENT_MESSAGE);
								}
								break;
							case RESTART_CURRENT_MESSAGE:
								messageQueue.put(PLAY_CURRENT_MESSAGE);
								break;
							case GET_POSITION:
								positionQueue.put(currentPosition);
								break;
							case GET_TOTAL_MESSAGES:
								positionQueue.put(totalMessages);
								break;
						}
						
						messageId = messageQueue.take();
					}
				}
				catch (Exception e)
				{
					java.io.StringWriter traceText = new java.io.StringWriter();
					java.io.PrintWriter pWriter = new java.io.PrintWriter(traceText,true);
					e.printStackTrace(pWriter);
					pWriter.close();
					throw new RuntimeException(pWriter.toString());
				}
				finally
				{
					if (speechEngine.isSpeaking())
					{
						speechEngine.stop();
					}
					speechEngine.shutdown();
				}
			}
		};
		
		controlThread = new Thread(messageInterpreter);
	}
	
	public String getCurrentText()
	{
		if ((messages!=null)&&(messages.length>0)&&(0<=currentPosition)&&(totalMessages>currentPosition))
			return messages[currentPosition];
		else
			return null;
	}
	
	public String getNextText()
	{
		if ((messages!=null)&&(messages.length>0)&&(-1<currentPosition)&&(totalMessages-1>currentPosition))
			return messages[currentPosition+1];
		else
			return null;
	}
	public String getPrevText()
	{
		if ((messages!=null)&&(messages.length>0)&&(0<currentPosition)&&(totalMessages>currentPosition))
			return messages[currentPosition-1];
		else
			return null;
	}
	
	
	public void start()
	{
		if (!controlThread.isAlive())
			controlThread.start();
		
	}
	
	public int getCurrentMessageIndex()
	{
		try
		{
			messageQueue.put(GET_POSITION);
			return positionQueue.take();
		}
		catch (Exception e)
		{
			
		}
		return 0;
	}
	
	public int getTotalMessages()
	{
		try
		{
			messageQueue.put(GET_TOTAL_MESSAGES);
			return positionQueue.take();
		}
		catch (Exception e)
		{
			
		}
		return 0;
	}
	public void updateMessages(String[] textMessages)
	{
		if ((textMessages!=null)&&(textMessages.length>0))
		{
			stopPlayingCurrentText();
			messages = textMessages;
			currentPosition=0;
			totalMessages = messages.length;
			
		}
	}
	
	public void playCurrentText()
	{
		
		sendMessage(PLAY_CURRENT_MESSAGE);
	}
	
	public void playNextText()
	{
		sendMessage(MOVE_TO_NEXT_MESSAGE);
	}
	
	public void playPrevText()
	{
		sendMessage(MOVE_TO_PREV_MESSAGE);
	}
	
	
	public void stopPlayingCurrentText()
	{
		sendMessage(STOP_CURRENT_MESSAGE);
	}
	
	
	
	public void shutdown()
	{
		sendMessage(QUIT);
	}

	private void sendMessage(int messageId)
	{
		try
		{
			messageQueue.put(messageId);
		}
		catch (Exception e)
		{
			
		}
	}
	
    @Override
    public void onInit(int Status)
    {
    	
        if (Status == TextToSpeech.SUCCESS)
        {
        	try
        	{
        		speechReadyP=true;
        	}
        	catch (Exception e)
        	{
        		
        	}
        }
       
    }
   
    
}
